--[[
* MapLib 2.0
* File: <AddOn>\MapLib\MapLib.lua
* $Revision: 140 $
* $Date: 2007-01-14 10:12:19 +0000 (Sun, 14 Jan 2007) $
* 
* Copyright (c) 2006-2007, Mery (Moritz Metelmann)
* All rights reserved.
* 
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* 
*    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
*    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
*    * Neither the name of the <ORGANIZATION> nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
]]--

local vmajor, vminor = "MapLib-2.0", tonumber(string.sub("$Revision: 140 $", 12, -3))

-- Version check: Only one major instance of MapLib can be installed, if another already is abort.
if (MapLib and MapLib.vmajor and (MapLib.vmajor ~= vmajor or MapLib.vminor >= vminor)) then return; end;

if (not MapLib) then MapLib = {}; end;
MapLib.vmajor = vmajor;
MapLib.vminor = vminor;

local L = MapLib.Localization;

if (not MapLib.mouseoverPOIList) then MapLib.mouseoverPOIList = {}; end;
if (not MapLib.MapLibButton) then MapLib.MapLibButton = {}; end;
if (not MapLib.POI) then MapLib.POI = {}; end;
if (not MapLib.Event) then MapLib.Event = {}; end;
if (not MapLib.Menu) then MapLib.Menu = {}; end;
if (not MapLib.MultiplePOIMenu) then MapLib.MultiplePOIMenu = {}; end;
if (not MapLib.Block) then MapLib.Block = {}; end;

MapLib.GetShownContinentID = function()
	if (MapLib.mapInfo[MapLib.mapShown].continentID) then
		return MapLib.mapInfo[MapLib.mapShown].continentID;
	elseif (MapLib.mapInfo[MapLib.mapShown].mapType == "CONTINENT") then
		return MapLib.mapShown;
	else
		return nil;
	end;
end;

MapLib.Menu.OnEnter = function()
	if (not this.isDisabled) then
		getglobal(this:GetName().."BG"):SetVertexColor(MapLib.colors[5].r, MapLib.colors[5].g, MapLib.colors[5].b);
	end;
end

MapLib.Menu.OnLeave = function()
	if (not this.isDisabled) then
		if (mod(this:GetID(), 2) == 0) then
			getglobal(this:GetName().."BG"):SetVertexColor(MapLib.colors[2].r, MapLib.colors[2].g, MapLib.colors[2].b);
		else
			getglobal(this:GetName().."BG"):SetVertexColor(MapLib.colors[1].r, MapLib.colors[1].g, MapLib.colors[1].b);
		end;
	end;
end;

MapLib.Menu.OnClick = function(button)
	if (not this.isDisabled) then
		if (button == "LeftButton") then
			-- stupid hack, fins a better solution
			if (getglobal(this:GetName().."Text"):GetText() == L["Close"]) then
				MapLibMenu:Hide();
			else
				MapLib.CloseMenus();
			end;
			if (MapLibMenu.menuShown == "LeftClickMenu") then
				if (this.onClick) then this.onClick(MapLibMenu.zone, MapLibMenu.x, MapLibMenu.y) end;
			elseif (MapLibMenu.menuShown == "POIMenu") then
				if (this.onClick) then this.onClick(MapLibMenu.poi) end;
			end;
		end;
	end;
end;

MapLib.Menu.BuildPOIMenu = function(poi)
	MapLibMenuHeader:SetText(L["POI Menu"]);
	local menuButtons = 0;
	local name;
	for i=1, getn(MapLib.poiMenu), 1 do
		-- check if that mod fits to teh zone and
		-- if the mod canonlyzone and if its a zone map
		if ( MapLib.poiMenu[i].forModIDs==nil or MapLib.IsInArray(poi.modID, MapLib.poiMenu[i].forModIDs) ) then
			menuButtons = menuButtons+1;
			if (menuButtons > MapLib.NUM_MENUBUTTONS) then MapLib.XML.CreateMenuButton() end;
			if (type(MapLib.poiMenu[i].name) == "function") then name = MapLib.poiMenu[i].name(poi); else name = MapLib.poiMenu[i].name end;
			getglobal("MapLibMenuButton"..menuButtons.."Text"):SetText(name);
			getglobal("MapLibMenuButton"..menuButtons).onClick = MapLib.poiMenu[i].callback;
			getglobal("MapLibMenuButton"..menuButtons):Show();
			if (MapLib.poiMenu[i].activeCheck) then MapLib.Menu.EnableButton(menuButtons); else MapLib.Menu.DisableButton(menuButtons); end;
		end;
	end;
	-- Hide this POI group (best idea I came up with so that the menu is never empty)
	menuButtons = menuButtons+1;
	if (menuButtons > MapLib.NUM_MENUBUTTONS) then MapLib.XML.CreateMenuButton() end;
	getglobal("MapLibMenuButton"..menuButtons.."Text"):SetText(L["Hide this POI group"]);
	getglobal("MapLibMenuButton"..menuButtons).onClick = MapLib.HideThisPOIGroup;
	getglobal("MapLibMenuButton"..menuButtons):Show();
	MapLib.Menu.EnableButton(menuButtons);
	-- Close Button
	menuButtons = menuButtons+1;
	if (menuButtons > MapLib.NUM_MENUBUTTONS) then MapLib.XML.CreateMenuButton() end;
	getglobal("MapLibMenuButton"..menuButtons.."Text"):SetText(L["Close"]);
	getglobal("MapLibMenuButton"..menuButtons).onClick = nil;
	getglobal("MapLibMenuButton"..menuButtons):Show();
	MapLib.Menu.EnableButton(menuButtons);
	
	MapLibMenu:SetHeight(21+menuButtons*16);
	MapLibMenu.menuShown = "POIMenu";
	MapLibMenu.poi = poi;
	for i=menuButtons+1, MapLib.NUM_MENUBUTTONS, 1 do
		getglobal("MapLibMenuButton"..i):Hide();
	end;
end;

MapLib.Menu.EnableButton = function(id)
	if (mod(getglobal("MapLibMenuButton"..id):GetID(), 2) == 0) then
		getglobal("MapLibMenuButton"..id.."BG"):SetVertexColor(MapLib.colors[2].r, MapLib.colors[2].g, MapLib.colors[2].b);
	else
		getglobal("MapLibMenuButton"..id.."BG"):SetVertexColor(MapLib.colors[1].r, MapLib.colors[1].g, MapLib.colors[1].b);
	end;
	getglobal("MapLibMenuButton"..id.."Text"):SetTextColor(MapLib.colors[7].r, MapLib.colors[7].g, MapLib.colors[7].b);
	getglobal("MapLibMenuButton"..id).isDisabled = false;
end;

MapLib.Menu.DisableButton = function(id)
	getglobal("MapLibMenuButton"..id.."BG"):SetVertexColor(MapLib.colors[9].r, MapLib.colors[9].g, MapLib.colors[9].b);
	getglobal("MapLibMenuButton"..id.."Text"):SetTextColor(MapLib.colors[8].r, MapLib.colors[8].g, MapLib.colors[8].b);
	getglobal("MapLibMenuButton"..id).isDisabled = true;
end;

MapLib.Menu.OnHide = function()
	MapLib.MultiplePOIMenu.ResetStaticHighlight();
end

MapLib.HideThisPOIGroup = function()
	if (MapLibSaved.poiDropDown[this:GetParent().poi.modID].isActivated) then 
		MapLibSaved.poiDropDown[this:GetParent().poi.modID].isActivated = false;
	else
		MapLibSaved.poiDropDown[this:GetParent().poi.modID].isActivated = true;
	end;
	MapLib.UpdatePOI("static");
end;

MapLib.ForcePOIUpdate = function()
	MapLib.UpdatePOI("static");
end;

-- /in 5 /script MapLib_BuildPOIMenu("duda"); MapLibMenu:Show();

MapLib.MultiplePOIMenu.OnEnter = function()
	-- set the tooltip of the note, in case the poi_menu is not shown for this button
	if ( MapLib.MultiplePOIMenu.menuShown ~= this:GetID() or not MapLibMenu:IsShown() ) then
		MapLib.CloseMenus("MapLibMultiplePOIMenu");
		MapLib.MultiplePOIMenu.tooltipShown = MapLib.poiDropDown[this.poi.modIndex].getTooltip(this.poi.id, this.poi.name);
		MapLib.MultiplePOIMenu.tooltipShown:Show();
		local heightShift = MapLib.MultiplePOIMenu.tooltipShown:GetHeight() - (this:GetTop() - MapLibButton:GetBottom()) - 5; -- -5 to make up for the tooltip edge
		if (heightShift < 0) then heightShift = 0; end;
		if (this:GetRight() <= 762) then
			MapLib.MultiplePOIMenu.tooltipShown:ClearAllPoints();
			MapLib.MultiplePOIMenu.tooltipShown:SetPoint("TOPLEFT", this, "TOPRIGHT", 0, 5 + heightShift);
		else
			MapLib.MultiplePOIMenu.tooltipShown:ClearAllPoints();
			MapLib.MultiplePOIMenu.tooltipShown:SetPoint("TOPRIGHT", this, "TOPLEFT", 0, 5 + heightShift);
		end;
	end;
	if (this:GetID() ~= MapLib.MultiplePOIMenu.staticHighlight) then
		getglobal(this:GetName().."BG"):SetVertexColor(MapLib.colors[5].r, MapLib.colors[5].g, MapLib.colors[5].b);
	end;
end

MapLib.MultiplePOIMenu.OnLeave = function()
	if (this:GetID() == MapLib.MultiplePOIMenu.staticHighlight) then return; end;
	if (mod(this:GetID(), 2) == 0) then
		getglobal(this:GetName().."BG"):SetVertexColor(MapLib.colors[2].r, MapLib.colors[2].g, MapLib.colors[2].b);
	else
		getglobal(this:GetName().."BG"):SetVertexColor(MapLib.colors[1].r, MapLib.colors[1].g, MapLib.colors[1].b);
	end;
	-- hide the current tooltip (if there is one)
	if (MapLib.MultiplePOIMenu.tooltipShown) then
		MapLib.MultiplePOIMenu.tooltipShown:Hide();
		MapLib.MultiplePOIMenu.tooltipShown = nil;
	end;
end

MapLib.MultiplePOIMenu.OnClick = function(button)
	if (button == "RightButton") then
		if (MapLib.MultiplePOIMenu.menuShown == this:GetID() and MapLibMenu:IsShown()) then
			MapLib.MultiplePOIMenu.menuShown = nil;
			MapLibMenu:Hide();
			MapLib.MultiplePOIMenu.OnEnter();
		else
			MapLib.MultiplePOIMenu.menuShown = this:GetID();
			MapLib.Menu.BuildPOIMenu(this.poi);
			MapLibMenu:Show();
			local heightShift = MapLibMenu:GetHeight() - (this:GetTop() - MapLibButton:GetBottom()) - 5; -- -5 to make up for the tooltip edge
			if (heightShift < 0) then heightShift = 0; end;
			if (this:GetRight() <= 762) then
				MapLibMenu:ClearAllPoints();
				MapLibMenu:SetPoint("TOPLEFT", this, "TOPRIGHT", 0, 5 + heightShift);
			else
				MapLibMenu:ClearAllPoints();
				MapLibMenu:SetPoint("TOPRIGHT", this, "TOPLEFT", 0, 5 + heightShift);
			end;
			-- if there is a tooltip hide it.
			if (MapLib.MultiplePOIMenu.tooltipShown) then
				MapLib.MultiplePOIMenu.tooltipShown:Hide();
				MapLib.MultiplePOIMenu.tooltipShown = nil;
			end;
			-- reset the old static hihglight
			MapLib.MultiplePOIMenu.ResetStaticHighlight();
			MapLib.MultiplePOIMenu.staticHighlight = this:GetID();
			getglobal(this:GetName().."BG"):SetVertexColor(MapLib.colors[6].r, MapLib.colors[6].g, MapLib.colors[6].b);
		end;
	elseif (this.poi.onLeftClick) then
		this.poi.onLeftClick(this.poi);
	end;
end

MapLib.MultiplePOIMenu.ResetStaticHighlight = function()
	if (MapLib.MultiplePOIMenu.staticHighlight) then
		if (mod(MapLib.MultiplePOIMenu.staticHighlight, 2) == 0) then
			getglobal("MapLibMultiplePOIMenuButton"..MapLib.MultiplePOIMenu.staticHighlight.."BG"):SetVertexColor(MapLib.colors[2].r, MapLib.colors[2].g, MapLib.colors[2].b);
		else
			getglobal("MapLibMultiplePOIMenuButton"..MapLib.MultiplePOIMenu.staticHighlight.."BG"):SetVertexColor(MapLib.colors[1].r, MapLib.colors[1].g, MapLib.colors[1].b);
		end;
	end;
	MapLib.MultiplePOIMenu.staticHighlight = nil;
end;

MapLib.OnLoad = function()
	MapLib.XML.CreateFrame();
	UIPanelWindows["MapLibFrame"] = { whileDead = 1, pushable = 0, area = "full" };

	MapLibFrame:SetScript("OnShow", MapLib.OnShow );
	MapLibFrame:SetScript("OnHide", MapLib.OnHide );
	MapLibFrame:SetScript("OnEvent", function(self, event, addon) 
		self:UnregisterEvent("ADDON_LOADED");
		MapLib.ChatHandler.VariablesLoaded();
		MapLib.WindowMode.VariablesLoaded();
		MapLib.BlizzardMaps.VariablesLoaded();
		MapLibFrame:SetScript("OnEvent", nil);
	end);
	MapLibFrame:RegisterEvent("ADDON_LOADED");
	MapLibButton:SetScript("OnClick", function() MapLib.MapLibButton.OnClick(arg1) end);
	MapLibButton:RegisterForClicks("LeftButtonUp", "RightButtonUp");
--	MapLibButton:SetScript("OnEvent", function() MapLib.MapLibButton.OnEvent(event) end);
	MapLibButton:SetScript("OnUpdate", function() MapLib.MapLibButton.OnUpdate() end);
--	MapLibButton:RegisterEvent("WORLD_MAP_UPDATE");
--	MapLibButton:RegisterEvent("PLAYER_ENTERING_WORLD");
	MapLib.EventHandler.RegisterEvent("MAPLIB", "WORLD_MAP_UPDATE", MapLib.Event.WORLD_MAP_UPDATE);
	MapLib.EventHandler.RegisterEvent("MAPLIB", "PLAYER_ENTERING_WORLD", MapLib.Event.PLAYER_ENTERING_WORLD);
	
	-- side menu test
--[[	local frame1 = CreateFrame("Frame", "Fram1", MapLibSideMenu);
	frame1:SetWidth(363);
	frame1:SetHeight(447);
	local texture = frame1:CreateTexture();
	texture:SetPoint("TOPLEFT", frame1, "TOPLEFT", 0, 0);
	texture:SetWidth(363);
	texture:SetHeight(447);
	texture:SetTexture(1, 0 , 0);
	frame1:SetFrameLevel(20);
	local frame2 = CreateFrame("Frame", "Fram2", MapLibSideMenu);
	frame2:SetWidth(363);
	frame2:SetHeight(447);
	local texture = frame2:CreateTexture();
	texture:SetPoint("TOPLEFT", frame2, "TOPLEFT", 0, 0);
	texture:SetWidth(363);
	texture:SetHeight(447);
	texture:SetTexture(1, 1 , 0);
	frame2:SetFrameLevel(20);
	
	MapLib.SideMenu.RegisterMenu("Test1", frame1);
	MapLib.SideMenu.RegisterMenu("Test2", frame2);
]]-- Test End.
end

MapLib.ShownMapIsBattlegroundMap = function()
	if (MapLib.mapShown and MapLib.mapInfo[MapLib.mapShown].mapType == "INSTANCE_BG") then
		return true;
	else
		return nil;
	end;
end;

MapLib.IsInBattleGround = function()
	local zoneID = MapLib.GetMapIDByName(GetRealZoneText());
	if (zoneID and MapLib.mapInfo[zoneID].mapType == "INSTANCE_BG") then
		return zoneID;
	end;
	return false;
end;

MapLib.ZoomOut = function()
	if (MapLib.mapInfo[MapLib.mapShown].zoomOutID) then
		MapLib.SetMapToID(MapLib.mapInfo[MapLib.mapShown].zoomOutID);
	-- this is only called if the map has not set a zoomOutID, so it doesn't really matter to what its set.
	elseif (MapLib.mapShown ~= MapLib.TOPLEVELMAP) then
		MapLib.SetMapToID(MapLib.TOPLEVELMAP);
	end;
end

MapLib.CloseMenus = function(exception)
	if (exception ~= "DropDown") then
		MapLib.DropDown.Close();
	end;
	if (exception ~= "LeftClickMenu" and MapLibMenu.menuShown == "LeftClickMenu") then
		MapLibMenu:Hide();
	end;
	if (exception ~= "POIMenu" and MapLibMenu.menuShown == "POIMenu") then
		MapLibMenu:Hide();
	end;
	if (exception ~= "MapLibMultiplePOIMenu") then
		MapLibMultiplePOIMenu:Hide();
		MapLibMultiplePOIMenu.isMenu = nil;
	end;
end;

MapLib.MapLibButton.OnClick = function(mouseButton, button)
	local adjustedX, adjustedY = MapLib.GetAdjustedCursorPosition(MapLibButton);
	if ( mouseButton == "LeftButton" ) then
		if ( not button ) then
			button = this;
		end
		local tempZone = MapLib.mapShown;
		MapLib.mapInfo[MapLib.mapShown].processMapClick( adjustedX, adjustedY );
		MapLib.CloseMenus("LeftClickMenu");
		if (not MapLib.lastClick) then MapLib.lastClick = {}; end;
		if (MapLib.lastClick.x == adjustedX and MapLib.lastClick.y == adjustedY and MapLib.lastClick.mapShown == MapLib.mapShown) then
			if (not MapLibMenu:IsVisible() and MapLib.lastClick.time+0.5>GetTime()) then
				-- show menu:
				-- built the buttons,
				MapLibMenu.x = adjustedX; MapLibMenu.y = adjustedY; MapLibMenu.zone = MapLib.mapShown;
				for i=1, getn(MapLib.menuButtons), 1 do
					if (i>MapLib.NUM_MENUBUTTONS) then MapLib.XML.CreateMenuButton() end;
					getglobal("MapLibMenuButton"..i.."Text"):SetText(MapLib.menuButtons[i][1]);
					getglobal("MapLibMenuButton"..i):Show();
					getglobal("MapLibMenuButton"..i).onClick = MapLib.menuButtons[i][2];
					if (not MapLib.menuButtons[i][3](MapLib.mapShown, adjustedX, adjustedY)) then
						MapLib.Menu.DisableButton(i);
					else
						MapLib.Menu.EnableButton(i);
					end;
				end;
				for i=getn(MapLib.menuButtons)+1, MapLib.NUM_MENUBUTTONS, 1 do
					getglobal("MapLibMenuButton"..i):Hide();
				end;
				-- set height and anchor
				MapLibMenu:SetHeight(21+getn(MapLib.menuButtons)*16);
				local x = adjustedX * MapLibButton:GetWidth();
				local y = adjustedY * MapLibButton:GetHeight();
				
				local heightShift = MapLibMenu:GetHeight() - (MapLibButton:GetHeight() - y);
				if (heightShift < 0) then heightShift = 0; end;
				if (x + MapLibMenu:GetWidth() + MapLib.SideMenu.verticalScrollvalue <= MapLibButton:GetWidth()) then
					MapLibMenu:ClearAllPoints();
					MapLibMenu:SetPoint("TOPLEFT", MapLibButton, "TOPLEFT", x, -y + heightShift);
				else
					MapLibMenu:ClearAllPoints();
					MapLibMenu:SetPoint("TOPRIGHT", MapLibButton, "TOPLEFT", x, -y + heightShift);
				end;
				MapLibMenuHeader:SetText(L["Menu"]);
				MapLibMenu:Show();
				MapLibMenu.menuShown = "LeftClickMenu";
			end;
		else
			MapLibMenu:Hide();
		end;
		-- save the position and shown map and time.
		MapLib.lastClick.x = adjustedX;
		MapLib.lastClick.y = adjustedY;
		MapLib.lastClick.mapShown = tempZone;
		MapLib.lastClick.time = GetTime();
	else
		if (MapLib.IsMenuShown()) then
			MapLib.CloseMenus();
		else
			MapLib.ZoomOut();
		end;
	end
end

MapLib.IsZoneMap = function()
	local mapType = MapLib.mapInfo[MapLib.mapShown].mapType;
	if ( mapType == "WORLD" or mapType == "CONTINENT") then
		return nil;
	else
		return true;
	end;
end;

MapLib.OnShow = function()
	MapLib.SetMapToCurrentZone();
end

MapLib.OnHide = function()
	SetMapToCurrentZone();
end

MapLib.SetMapToCurrentZone = function()
	local zoneID = MapLib.GetMapIDByName(GetRealZoneText());
	if (zoneID) then
		MapLib.SetMapToID(zoneID);
	else
		MapLib.SetMapToID(MapLib.TOPLEVELMAP);
	end;
end;

MapLib.MapLibButton.OnEvent = function(event)
	if (event == "WORLD_MAP_UPDATE" and (MapLib.mapToShow == "BLIZZARD" or ( not MapLib.mapToShow and not MapLib.IsInBattleGround() ))) then
		MapLib.UpdateMap(MapLib.GetCurrentBlizzardMapMapID());
		MapLib.mapToShow = nil;
	elseif (event == "WORLD_MAP_UPDATE" and MapLib.mapToShow) then
		DevTools_Dump(MapLib.mapToShow);
		if (MapLib.mapInfo[MapLib.mapToShow].mapType~="INSTANCE_BG" and strsub(MapLib.mapInfo[MapLib.mapToShow].mapType, 1, 9) == "INSTANCE_") then
			-- hmm can I ever get here? I'll leave it in: if yes there will be reports of this next 2 lines erroring
			DevTools_Dump("hallo");
			MapLib.Event:ScheduleEvent(MapLib.UpdateMap, 0.1, MapLib.mapToShow);
			MapLib.mapToShow = nil;
		else
			MapLib.UpdateMap(MapLib.mapToShow);
			MapLib.mapToShow = nil;
		end;
	elseif (event == "WORLD_MAP_UPDATE") then
		-- this is assumed to be a BG update of the icons
		MapLib.UpdatePOI("static");
	elseif (event == "PLAYER_ENTERING_WORLD") then
		MapLib.SetMapToCurrentZone();
	end;
end

MapLib.Event.PLAYER_ENTERING_WORLD = function()
	MapLib.SetMapToCurrentZone();
end;

MapLib.Event.WORLD_MAP_UPDATE = function()
	if (MapLib.mapToShow == "BLIZZARD" or ( not MapLib.mapToShow and not MapLib.IsInBattleGround() )) then
		MapLib.UpdateMap(MapLib.GetCurrentBlizzardMapMapID());
		MapLib.mapToShow = nil;
	elseif (MapLib.mapToShow) then
--		if (MapLib.mapInfo[MapLib.mapToShow].mapType~="INSTANCE_BG" and strsub(MapLib.mapInfo[MapLib.mapToShow].mapType, 1, 9) == "INSTANCE_") then
			-- Don't update until next frame to showthe loading stuff.
			-- this is currently disabled, since converting to blp fixed the loading time
--			MapLib.Event:ScheduleEvent(MapLib.UpdateMap, 0.1, MapLib.mapToShow);
--			MapLib.mapToShow = nil;
--		else
			MapLib.UpdateMap(MapLib.mapToShow);
			MapLib.mapToShow = nil;
--		end;
	else
		-- this is assumed to be a BG update of the icons
		MapLib.UpdatePOI("static");
	end;
end;

MapLib.GetAdjustedCursorPosition = function(relativeFrame)
	local x, y = GetCursorPosition();
	x = x / relativeFrame:GetEffectiveScale();
	y = y / relativeFrame:GetEffectiveScale();

	local centerX, centerY = relativeFrame:GetCenter();
	if (not centerX) then return 0, 0; end;
	local width = relativeFrame:GetWidth();
	local height = relativeFrame:GetHeight();
	local adjustedY = (centerY + (height/2) - y ) / height;
	local adjustedX = (x - (centerX - (width/2))) / width;
	
	return adjustedX, adjustedY;
end

MapLib.MultiplePOIMenu.SetPoints = function()
	-- find out how many are shown
	local shown = MapLib.NUM_MULTIPLEPOIMENUBUTTONS;
	for i = 1, MapLib.NUM_MULTIPLEPOIMENUBUTTONS, 1 do
		if (not getglobal("MapLibMultiplePOIMenuButton"..i):IsShown()) then
			shown = i-1;
			break;
		end;
	end;
	-- if > 20 then built 2 rows, otherwise build one.
	if (shown < MapLib.MULTIPLEPOIMENU_MAKETWOROWS) then
		for i = 1, shown, 1 do
			if (i == 1) then
				getglobal("MapLibMultiplePOIMenuButton"..i):SetPoint("TOP", MapLibMultiplePOIMenuHeaderFrame, "BOTTOM", 0, 0);
			else
				getglobal("MapLibMultiplePOIMenuButton"..i):SetPoint("TOP", "MapLibMultiplePOIMenuButton"..(i - 1), "BOTTOM");
			end
		end;
		MapLibMultiplePOIMenu:SetWidth(160);
		MapLibMultiplePOIMenu:SetHeight(21+shown*16);
	else
		local firstRow = ceil(shown/2);
		for i = 1, shown, 1 do
			if (i == 1) then
				getglobal("MapLibMultiplePOIMenuButton"..i):SetPoint("TOP", MapLibMultiplePOIMenuHeaderFrame, "BOTTOM", -75, 0);
			elseif (i == ceil(shown/2) + 1) then
				getglobal("MapLibMultiplePOIMenuButton"..i):SetPoint("TOP", MapLibMultiplePOIMenuHeaderFrame, "BOTTOM", 75, 0);
			else
				getglobal("MapLibMultiplePOIMenuButton"..i):SetPoint("TOP", "MapLibMultiplePOIMenuButton"..(i - 1), "BOTTOM");
			end
		end;
		MapLibMultiplePOIMenu:SetWidth(310);
		MapLibMultiplePOIMenu:SetHeight(21+ceil(shown/2)*16);
	end;	
end;

MapLib.MapLibButton.OnUpdate = function()
	local width = this:GetWidth();
	local height = this:GetHeight();
	-- registered mods for onupdate
	MapLib.UpdatePOI("onUpdate");
	
	-- create the tooltip if needed
	MapLibFrame.poiHighlight = nil;
	if (MapLib.cursorIsOverPOI) then
		local poi, name, textureIndex;
		MapLib.mouseoverPOIList = {};
		local numOverPOIs = 0;
		for i = MapLib.nextStaticPOI, MapLib.nextOnUpdatePOI-1, 1 do
			-- check on updatePOI's first.
			poi = getglobal("MapLibPOI"..i);
			if ( MouseIsOver(poi) and poi:IsVisible() ) then
				numOverPOIs = numOverPOIs + 1;
				tinsert(MapLib.mouseoverPOIList, poi);
			end;
		end;
		for i = 1, MapLib.nextStaticPOI - 1, 1 do
			poi = getglobal("MapLibPOI"..i); -- /in 5 /dump MouseIsOver(MapLibPOI14);
			if ( MouseIsOver(poi) and poi:IsVisible() ) then
				-- EXCEPTION: If Blizzard POI and texture == 15 then don't show, but set area Text, also rememberit
				textureIndex = nil;
				if ( poi.modID == "BLIZZARD_POI" and (MapLib.mapShown == MapLib.GetCurrentBlizzardMapMapID() or MapLib.ShownMapIsBattlegroundMap()) ) then
					name, _, textureIndex = MapLib_GetNameDescriptionTextureIndex_BlizzardReplace(poi.id);
				end;
				if (textureIndex == 15) then
					MapLibFrameAreaLabel:SetText(name);
					MapLibFrame.poiHighlight = true;
				else
					numOverPOIs = numOverPOIs + 1;
					tinsert(MapLib.mouseoverPOIList, poi);
				end;
			end;
		end;
		--DevTools_Dump(tempPOI);
		-- in case a menu is shown, just don't show any tooltip
		-- (its here so that invisible POI's still work the blizzard way)
		if ( MapLib.IsMenuShown() ) then numOverPOIs = 0; end;
		
		if (numOverPOIs == 0) then
			if (MapLib.tooltipShown) then
				MapLib.tooltipShown:Hide();
				MapLib.tooltipShown = nil;
			end;
			SetCursor(nil);
		elseif (numOverPOIs == 1) then
			local poi = MapLib.mouseoverPOIList[1];
			local oldTooltip = MapLib.tooltipShown;
			MapLib.tooltipShown = MapLib.poiDropDown[poi.modIndex].getTooltip(poi.id, poi.name);
			if (oldTooltip and oldTooltip ~= MapLib.tooltipShown) then oldTooltip:Hide(); end;
			MapLib.tooltipShown:Show();
		else
			-- else (more than one) show the multinote tooltip (reset all linesin it that are not used, and set height).
			for i, v in ipairs(MapLib.mouseoverPOIList) do
				if (i > MapLib.NUM_MULTIPLEPOIMENUBUTTONS) then MapLib.XML.CreateMultiplePOIMenuButton(); end;
				local button = getglobal("MapLibMultiplePOIMenuButton"..i);
				local text = getglobal("MapLibMultiplePOIMenuButton"..i.."Text");
				local icon = getglobal("MapLibMultiplePOIMenuButton"..i.."Icon");
				-- show button
				icon:SetTexture(getglobal(v:GetName().."Texture"):GetTexture());
				icon:SetTexCoord(getglobal(v:GetName().."Texture"):GetTexCoord());
				icon:SetVertexColor(getglobal(v:GetName().."Texture"):GetVertexColor());
				text:SetText(v.name);
				button.poi = v;
				button:Show();
			end;
			MapLibMultiplePOIMenuHeader:SetText("Multiple POI");
			for i=getn(MapLib.mouseoverPOIList)+1, MapLib.NUM_MULTIPLEPOIMENUBUTTONS, 1 do
				getglobal("MapLibMultiplePOIMenuButton"..i):Hide();
			end;
			MapLib.MultiplePOIMenu.SetPoints();
			if (not MapLib.tooltipShown or MapLib.tooltipShown == MapLibMultiplePOIMenu) then
				MapLib.tooltipShown = MapLibMultiplePOIMenu;
				MapLib.tooltipShown:Show();
			else
				MapLib.tooltipShown:Hide();
				MapLib.tooltipShown = MapLibMultiplePOIMenu;
				MapLib.tooltipShown:Show();
			end;
		end;
	else
		if (MapLib.tooltipShown) then
			MapLib.tooltipShown:Hide();
			MapLib.tooltipShown = nil;
		end;
		SetCursor(nil);
	end;
	
	if (MapLib.tooltipShown and MapLib.tooltipShown:IsVisible()) then
		local x, y = GetCursorPosition();
		x = x / MapLibButton:GetEffectiveScale();
		y = y / MapLibButton:GetEffectiveScale();

		local centerX, centerY = MapLibButton:GetCenter();
		y = (centerY + (height/2) - y );
		x = (x - (centerX - (width/2)));
		
		local heightShift = MapLib.tooltipShown:GetHeight() - (MapLibButton:GetHeight() - y);
		if (heightShift < 0) then heightShift = 0; end;
		if (x + MapLib.tooltipShown:GetWidth() + MapLib.SideMenu.verticalScrollvalue <= MapLibButton:GetWidth()) then
			MapLib.tooltipShown:ClearAllPoints();
			MapLib.tooltipShown:SetPoint("TOPLEFT", MapLibButton, "TOPLEFT", x, -y + heightShift);
			SetCursor(MapLib.PATH.."\\Cursor\\MiniArrow.BLP");
		else
			MapLib.tooltipShown:ClearAllPoints();
			MapLib.tooltipShown:SetPoint("TOPRIGHT", MapLibButton, "TOPLEFT", x, -y + heightShift);
			SetCursor(nil);
		end;
	end;

	-- Only do UpdateMapHighlight if the map is not blocked:
	if (MapLibBlockButton:IsShown()) then
		MapLibFrameAreaLabel:SetText("");
		MapLibHighlight:Hide();
	else
		-- Update Map Highligh (last because of those tricky not shown POI's);
		local alphaMode, name, fileName, texPercentageX, texPercentageY, textureX, textureY, scrollChildX, scrollChildY = MapLib.mapInfo[MapLib.mapShown].updateMapHighlight( MapLib.GetAdjustedCursorPosition(this) );
	
		MapLibFrame.areaName = name;
		if ( not MapLibFrame.poiHighlight ) then
			MapLibFrameAreaLabel:SetText(name);
		end
		if ( fileName ) then
			MapLibHighlight:SetTexCoord(0, texPercentageX, 0, texPercentageY);
			MapLibHighlight:SetTexture(fileName);
			textureX = textureX * width;
			textureY = textureY * height;
			scrollChildX = scrollChildX * width;
			scrollChildY = -scrollChildY * height;
			if ( (textureX > 0) and (textureY > 0) ) then
				MapLibHighlight:SetWidth(textureX);
				MapLibHighlight:SetHeight(textureY);
				MapLibHighlight:SetPoint("TOPLEFT", "MapLibDetailFrame", "TOPLEFT", scrollChildX, scrollChildY);
				MapLibHighlight:SetBlendMode(alphaMode);
				MapLibHighlight:Show();
				--WorldMapFrameAreaLabel:SetPoint("TOP", "WorldMapHighlight", "TOP", 0, 0);
			end;
		else
			MapLibHighlight:Hide();
		end;
	end;
end

-- Get the mapID of the internally set wow blizzard map. This may not be the map shown in the MapLib map.
MapLib.GetCurrentBlizzardMapMapID = function()
	local continent, zone = GetCurrentMapContinent(), GetCurrentMapZone();
	if (continent == MapLib.BG_CONTINENT_NUMBER) then
		local name, _, _ = GetMapInfo();
		if (not name) then
			return "WO_CM";
		else
			return MapLib.bgFilePathToInstanceID[name];
		end;
	else	
		return MapLib.blizzardConversion[continent][zone];
	end;	
end;

MapLib.ConvertToContinentCoordinates = function(mapID, x, y)
	-- ERRORS IS NO MAPID IS GIVEN!
	if (MapLib.mapInfo[mapID].scale) then
		-- if not continentID is set then its a continent
		local continentID = MapLib.mapInfo[mapID].continentID or mapID;
		return x*MapLib.mapInfo[mapID].scale+MapLib.mapInfo[mapID].xoffset, y*MapLib.mapInfo[mapID].scale+MapLib.mapInfo[mapID].yoffset, continentID;
	end;
	-- return sucess, continentID, x, y;
	-- no conversion possible:
	return 0, 0, nil;
end;

MapLib.RegisterZone = function(mapID, mapName, continentID, zoomOutID, mapType, texturePath, processMapClick, updateMapHighlight, getNumMapOverlays, getMapOverlayInfo, getPlayerMapPosition, ggetCorpseMapPosition, getDeathReleasePosition, scale, xoffset, yoffset, protectOverwrite)
	-- protect Overwrite is not included yet.
	-- no protection to overwrite mapID's with different mapTypes
	-- no overwirte at all since table.insert

	-- mapType = "NO_TYPE", "WORLD", "CONTINENT", "BLIZZARD", "INSTANCE_NORMAL", "INSTANCE_LOCKOUT", "INSTANCE_BG"

	if (not MapLib.mapInfo) then MapLib.mapInfo = {}; end;
	local mapInfo = {
		mapName = mapName,
		continentID = continentID,
		zoomOutID = zoomOutID,
		mapType = mapType,
		texturePath = texturePath,
		processMapClick = processMapClick,
		updateMapHighlight = updateMapHighlight,
		getNumMapOverlays = getNumMapOverlays,
		getMapOverlayInfo = getMapOverlayInfo,
		getPlayerMapPosition = getPlayerMapPosition,
		getCorpseMapPosition = ggetCorpseMapPosition,
		getDeathReleasePosition = getDeathReleasePosition,
		scale = scale,
		xoffset = xoffset,
		yoffset = yoffset,
	};
	
	if (mapType == "WORLD") then
		if (mapID == "WO_AZ") then -- to be able to add another world map (cosmic)
			if (not MapLib.blizzardConversion) then MapLib.blizzardConversion = {}; end;
			if (not MapLib.blizzardConversion[0]) then MapLib.blizzardConversion[0] = {}; end;
			MapLib.blizzardConversion[0][0] = "WO_AZ";
			MapLib.blizzardConversion["WO_AZ"] = {continent = 0, zone = 0};
		end;
		if (mapID == "WO_CM") then
			if (not MapLib.blizzardConversion) then MapLib.blizzardConversion = {}; end;
--			if (not MapLib.blizzardConversion[-1]) then MapLib.blizzardConversion[-1] = {}; end;
--			MapLib.blizzardConversion[-1][0] = "WO_CM";
			MapLib.blizzardConversion["WO_CM"] = {continent = -1, zone = 0};
		end;
		MapLib.mapInfo[mapID] = mapInfo;
		return true;
	elseif (mapType == "CONTINENT") then
		local continentNumber = MapLib.ReturnNumber(mapName, GetMapContinents());
		if ( continentNumber ) then
			if (not MapLib.blizzardConversion) then MapLib.blizzardConversion = {}; end;
			if (not MapLib.blizzardConversion[continentNumber]) then MapLib.blizzardConversion[continentNumber] = {}; end;
			MapLib.blizzardConversion[continentNumber][0] = mapID;
			MapLib.blizzardConversion[mapID] = {continent = continentNumber, zone = 0};
			if (not MapLib.continents) then MapLib.continents = {}; end;
			table.insert(MapLib.continents, mapName);
			table.sort(MapLib.continents);
			MapLib.mapInfo[mapID] = mapInfo;
			return true;			
		end
	elseif (mapType == "BLIZZARD") then
		if (MapLib.blizzardConversion and MapLib.blizzardConversion[continentID]) then
			local continentNumber = MapLib.blizzardConversion[continentID].continent;
			local zoneNumber = MapLib.ReturnNumber(mapName, GetMapZones(continentNumber));
			if ( zoneNumber ) then
				MapLib.blizzardConversion[continentNumber][zoneNumber] = mapID;
				MapLib.blizzardConversion[mapID] = {continent = continentNumber, zone = zoneNumber};
				if (not MapLib.zones) then MapLib.zones = {}; end;
				if (not MapLib.zones[continentID]) then MapLib.zones[continentID] = {}; end;
				table.insert(MapLib.zones[continentID], mapName);
				table.sort(MapLib.zones[continentID]);
				MapLib.mapInfo[mapID] = mapInfo;
				return true;			
			end;
		end;
	elseif (mapType == "ZONE") then
		if (not MapLib.zones) then MapLib.zones = {}; end;
		if (not MapLib.zones[continentID]) then MapLib.zones[continentID] = {}; end;
		table.insert(MapLib.zones[continentID], mapName);
		table.sort(MapLib.zones[continentID]);
		MapLib.mapInfo[mapID] = mapInfo;
		return true;
	elseif ( strsub(mapType, 1, 9) == "INSTANCE_" ) then
		if (not MapLib.instances) then MapLib.instances = {}; end;
		if (not MapLib.instances[continentID]) then MapLib.instances[continentID] = {}; end;
		table.insert(MapLib.instances[continentID], mapName);
		table.sort(MapLib.instances[continentID]);
		MapLib.mapInfo[mapID] = mapInfo;
		return true;
	elseif (mapType == "NO_TYPE") then
		MapLib.mapInfo[mapID] = mapInfo;
		return true;
	end;
	-- if we come till here there was an error
	return false;
end

MapLib.ReturnNumber = function(name, ...)
	for i=1, select("#", ...), 1 do
		if (name ==	select(i, ...)) then
			return i;
		end;
	end;
	return nil;
end

MapLib.IsInArray = function(item, array)
	for k, v in pairs(array) do
		if (item == v) then return true; end;
	end;
	return nil;
end;

MapLib.GetMapIDByName = function(name)
	for key, _ in pairs(MapLib.mapInfo) do
		if (MapLib.mapInfo[key].mapName == name) then
			return key;
		end
	end
	-- not found, return nil?
	return nil;
end

MapLib.IsBlizzardMap = function(mapID)

end

MapLib.IsMenuShown = function()
	if (MapLibMenu:IsVisible() or MapLibMultiplePOIMenu.isMenu) then
		return true;
	else
		return nil;
	end;
end;

MapLib.UpdateMap = function(mapID)
	-- Dont update if the frame is not shown.
	if (not MapLibFrame:IsShown()) then return; end;

	MapLib.mapShown = mapID;
	MapLib.EventHandler.TriggerEvent("MAPLIB_UPDATE_MAP", mapID);
	
	-- Hide the loading frame in case it was shown.
	-- currently disabled since I don't need it thanks to blp convertors
	-- MapLibFrameLoading:Hide();
	
	-- close drop down menus
	MapLib.CloseMenus();
	
	-- update the text in the dropdown buttons.
	if (MapLib.GetShownContinentID()) then
		MapLibContinentDropDownText:SetText(MapLib.mapInfo[MapLib.GetShownContinentID()].mapName);
	else
		MapLibContinentDropDownText:SetText("");
	end;
	if (MapLib.mapInfo[mapID].mapType == "BLIZZARD" or MapLib.mapInfo[mapID].mapType == "ZONE") then
		MapLibZoneDropDownText:SetText(MapLib.mapInfo[mapID].mapName);
		MapLibInstanceDropDownText:SetText("");
	elseif ( strsub(MapLib.mapInfo[mapID].mapType, 1, 9) == "INSTANCE_" ) then
		MapLibInstanceDropDownText:SetText(MapLib.mapInfo[mapID].mapName);
		MapLibZoneDropDownText:SetText("");
	else
		MapLibInstanceDropDownText:SetText("");
		MapLibZoneDropDownText:SetText("");
	end

	for i=1, NUM_WORLDMAP_DETAIL_TILES, 1 do
		getglobal("MapLibDetailTile"..i):SetTexture(MapLib.mapInfo[mapID].texturePath..i);
	end;

	local numOverlays = MapLib.mapInfo[mapID].getNumMapOverlays();
	local textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY;
	local textureCount = 0, neededTextures;
	local texture;
	local texturePixelWidth, textureFileWidth, texturePixelHeight, textureFileHeight;
	local numTexturesWide, numTexturesTall;
	for i=1, numOverlays do
		textureName, textureWidth, textureHeight, offsetX, offsetY, mapPointX, mapPointY = MapLib.mapInfo[mapID].getMapOverlayInfo(i);
		numTexturesWide = ceil(textureWidth/256);
		numTexturesTall = ceil(textureHeight/256);
		neededTextures = textureCount + (numTexturesWide * numTexturesTall);
		if ( neededTextures > MapLib.NUM_OVERLAYS ) then
			for j=MapLib.NUM_OVERLAYS+1, neededTextures do
				MapLibDetailFrame:CreateTexture("MapLibOverlay"..j, "ARTWORK");
			end
			MapLib.NUM_OVERLAYS = neededTextures;
		end
		for j=1, numTexturesTall do
			if ( j < numTexturesTall ) then
				texturePixelHeight = 256;
				textureFileHeight = 256;
			else
				texturePixelHeight = mod(textureHeight, 256);
				if ( texturePixelHeight == 0 ) then
					texturePixelHeight = 256;
				end
				textureFileHeight = 16;
				while(textureFileHeight < texturePixelHeight) do
					textureFileHeight = textureFileHeight * 2;
				end
			end
			for k=1, numTexturesWide do
				textureCount = textureCount + 1;
				texture = getglobal("MapLibOverlay"..textureCount);
				if ( k < numTexturesWide ) then
					texturePixelWidth = 256;
					textureFileWidth = 256;
				else
					texturePixelWidth = mod(textureWidth, 256);
					if ( texturePixelWidth == 0 ) then
						texturePixelWidth = 256;
					end
					textureFileWidth = 16;
					while(textureFileWidth < texturePixelWidth) do
						textureFileWidth = textureFileWidth * 2;
					end
				end
				texture:SetWidth(texturePixelWidth);
				texture:SetHeight(texturePixelHeight);
				texture:SetTexCoord(0, texturePixelWidth/textureFileWidth, 0, texturePixelHeight/textureFileHeight);
				texture:SetPoint("TOPLEFT", offsetX + (256 * (k-1)), -(offsetY + (256 * (j - 1))));
				texture:SetTexture(textureName..(((j - 1) * numTexturesWide) + k));
				texture:Show();
			end
		end
	end
	for i=textureCount+1, MapLib.NUM_OVERLAYS do
		getglobal("MapLibOverlay"..i):Hide();
	end
	
	MapLib.UpdatePOI("static");
	-- to make sure all POI's are initializied when it gets grayed out.
	MapLib.UpdatePOI("onUpdate");
	-- grayout again in case the map view is blocked
	MapLib.Block.RedoGrayscale();
end

MapLib.UpdatePOI = function(method)
	if (method == "static") then MapLib.nextStaticPOI = 1; else MapLib.nextOnUpdatePOI = MapLib.nextStaticPOI; end;
	local poi, poiTexture, id, name, texture, x, y, style, priorityLevel, onLeftClick, nextIcon;
	for i, _ in ipairs(MapLib.poiDropDown) do
		if (MapLibSaved.poiDropDown[MapLib.poiDropDown[i].nameID].isActivated and ((not MapLib.poiDropDown[i].isOnUpdate and method == "static") or (MapLib.poiDropDown[i].isOnUpdate and method == "onUpdate")) ) then
			for j = 1, MapLib.poiDropDown[i].getNumPOI(), 1 do
				if (method == "static") then nextIcon = MapLib.nextStaticPOI else nextIcon = MapLib.nextOnUpdatePOI; end;
				id, name, texture, x, y, style, priorityLevel, onLeftClick = MapLib.poiDropDown[i].getPOI(j);
				
				if (not style or MapLibSaved.poiDropDown[MapLib.poiDropDown[i].nameID][style]) then
					if (nextIcon > MapLib.NUM_POIS) then MapLib.XML.CreatePOI(); end;
					poi = getglobal("MapLibPOI"..nextIcon);
					poiTexture = getglobal("MapLibPOI"..nextIcon.."Texture");
	
					x = x * MapLibButton:GetWidth();
					y = -y * MapLibButton:GetHeight();
					poi.name = name;
					poi.modID = MapLib.poiDropDown[i].nameID;
					poi.modIndex = i;
					poi.id = id;
					poi.onLeftClick = onLeftClick;
					poi:SetPoint("CENTER", MapLibButton, "TOPLEFT", x, y);
					poi:SetFrameLevel(priorityLevel+2);
					poiTexture:SetTexture(texture.file);
					if (texture.size) then
						poi:SetWidth(texture.size);
						poi:SetHeight(texture.size);
					else
						poi:SetWidth(16);
						poi:SetHeight(16);
					end;
					if (texture.tcoordMinX) then poiTexture:SetTexCoord(texture.tcoordMinX, texture.tcoordMaxX, texture.tcoordMinY, texture.tcoordMaxY); else poiTexture:SetTexCoord(0, 1, 0, 1); end;
					if (texture.colorR) then poiTexture:SetVertexColor(texture.colorR, texture.colorG, texture.colorB, texture.colorA); else poiTexture:SetVertexColor(1, 1, 1, 1); end;
					poi:Show();
					if (method == "static") then MapLib.nextStaticPOI = MapLib.nextStaticPOI+1; else MapLib.nextOnUpdatePOI = MapLib.nextOnUpdatePOI+1; end;
				end;
			end;
		end;
		if (MapLib.poiDropDown[i].nameID == "BLIZZARD_POI" and not MapLibSaved.poiDropDown[MapLib.poiDropDown[i].nameID].isActivated and method=="static") then
			MapLib.TempAlwaysDrawBlizzardsInvisiblePOIsFix(i);
		end;
	end;
	if (method == "static") then nextIcon = MapLib.nextStaticPOI else nextIcon = MapLib.nextOnUpdatePOI; end;
	for i=nextIcon, MapLib.NUM_POIS, 1 do
		getglobal("MapLibPOI"..i):Hide();
	end;
end;

-- THIS IS A (HOPEFULLY) TEMP FUNCTION TO DARW THE INVISIBLE BLIZZARD POIS
-- IF DRAWING OF BLIZZARD_POI IS OFF, MAINLY COPY PASTE
MapLib.TempAlwaysDrawBlizzardsInvisiblePOIsFix = function(i)
	if (not MapLib.mapShown == MapLib.GetCurrentBlizzardMapMapID()) then return; end;
	for j = 1, MapLib.poiDropDown[i].getNumPOI(), 1 do
		name, description, textureIndex, x, y = GetMapLandmarkInfo(j);
		
		if (textureIndex == 15) then
			if (MapLib.nextStaticPOI > MapLib.NUM_POIS) then MapLib.XML.CreatePOI(); end;
			poi = getglobal("MapLibPOI"..MapLib.nextStaticPOI);
			poiTexture = getglobal("MapLibPOI"..MapLib.nextStaticPOI.."Texture");
			x = x * MapLibButton:GetWidth();
			y = -y * MapLibButton:GetHeight();
			poi.name = name;
			poi.modID = MapLib.poiDropDown[i].nameID;
			poi.modIndex = i;
			poi.id = j;
			poi.onLeftClick = nil;
			poi:SetPoint("CENTER", MapLibButton, "TOPLEFT", x, y);
			poiTexture:SetTexture("Interface\\Minimap\\POIIcons");
			poiTexture:SetWidth(16);
			poiTexture:SetHeight(16);
			poiTexture:SetTexCoord(WorldMap_GetPOITextureCoords(15));
			poi:Show();
			MapLib.nextStaticPOI = MapLib.nextStaticPOI + 1;
		end;
	end;
end;

MapLib.GetCurrentPlayerMapID = function()
end

MapLib.POI.OnClick = function(button)
	-- it no on left click, then processMapClick
	if (button == "LeftButton") then
		if ( this.onLeftClick and not MapLibMultiplePOIMenu:IsVisible() ) then
			this.onLeftClick(this);
		else
			MapLib.MapLibButton.OnClick(button, MapLibButton); 
		end;
	else -- right click
		if (MapLib.IsMenuShown()) then
			MapLib.CloseMenus();
		elseif (not MapLib.tooltipShown) then -- Zoom out on Blizzards invisible POIs
			MapLib.ZoomOut();
		else
			if (MapLibMultiplePOIMenu:IsVisible()) then
				MapLib.CloseMenus("MapLibMultiplePOIMenu");
				MapLib.tooltipShown = nil;
				MapLibMultiplePOIMenu.isMenu = true;
				MapLibMultiplePOIMenuHeader:SetText(L["Multiple POI Menu"]);
				-- make multiplePOI the menu.
				-- add a close button?
			else
				MapLib.CloseMenus();
				-- open POI Menu MapLib_OpenPOIMenu(topLeftX, topLefty, topRightX, topRightY);
				MapLib.Menu.BuildPOIMenu(this);
				local x, y = GetCursorPosition();
				x = x / MapLibButton:GetEffectiveScale();
				y = y / MapLibButton:GetEffectiveScale();

				local centerX, centerY = MapLibButton:GetCenter();
				y = (centerY + (MapLibButton:GetHeight()/2) - y );
				x = (x - (centerX - (MapLibButton:GetWidth()/2)));

				local heightShift = MapLibMenu:GetHeight() - (MapLibButton:GetHeight() - y) - 5; -- -5 to make up for the tooltip edge
				if (heightShift < 0) then heightShift = 0; end;
				if (x + MapLibMenu:GetWidth() + MapLib.SideMenu.verticalScrollvalue <= MapLibButton:GetWidth()) then
					MapLibMenu:ClearAllPoints();
					MapLibMenu:SetPoint("TOPLEFT", MapLibButton, "TOPLEFT", x, -y + heightShift);
				else
					MapLibMenu:ClearAllPoints();
					MapLibMenu:SetPoint("TOPRIGHT", MapLibButton, "TOPLEFT", x, -y + heightShift);
				end;
				
				MapLibMenu:Show();
			end;
		end;
	end;
end

MapLib.POI.OnEnter = function()
	MapLib.cursorIsOverPOI = true;
end

MapLib.POI.OnLeave = function()
	MapLib.cursorIsOverPOI = false;
end

-- REVIEW THIS WHOLE FUNCTION!! (Probably not right with selfmade maps.)
MapLib.SetMapToID = function(mapID)
	if (MapLib.mapInfo[mapID]) then
		if (MapLib.mapInfo[mapID].mapType == "WORLD" or MapLib.mapInfo[mapID].mapType == "CONTINENT" or MapLib.mapInfo[mapID].mapType == "BLIZZARD") then
			MapLib.mapToShow = "BLIZZARD";
			SetMapZoom(MapLib.blizzardConversion[mapID].continent, MapLib.blizzardConversion[mapID].zone);
		-- I DOUBT the next line is correct, probably belong NORMAL and LOCKOUT more down because even when the zone text matches I want to have under control which map is shown (on Blizzards end).
		-- after the above comment the line got changed from an "or or or" statement...
		elseif ( strsub(MapLib.mapInfo[mapID].mapType, 1, 9) == "INSTANCE_" ) then
			if (MapLib.mapInfo[mapID].mapName == GetRealZoneText() and MapLib.mapInfo[mapID].mapType == "INSTANCE_BG") then
				MapLib.mapToShow = "BLIZZARD";
				SetMapToCurrentZone();
			else
				MapLib.mapToShow = mapID;
				-- In case we load a map from an AddOns folder
				-- (assumed this only happens for non Blizzard maps)
				-- show the little loading sign, since it may take some seconds
				-- This is currently disabled, since converting to blp fixed the loading time
				-- if (MapLib.mapInfo[mapID].mapType ~= "INSTANCE_BG" and mapID ~= MapLib.mapShown) then MapLibFrameLoading:Show(); end;
				if (MapLib.mapInfo[mapID].continentID) then
					SetMapZoom(MapLib.blizzardConversion[MapLib.mapInfo[mapID].continentID].continent, MapLib.blizzardConversion[MapLib.mapInfo[mapID].continentID].zone);
				else
					SetMapZoom(0);
				end;
			end;
		else
			MapLib.mapToShow = mapID;
			if (MapLib.mapInfo[mapID].continentID) then
				SetMapZoom(MapLib.blizzardConversion[MapLib.mapInfo[mapID].continentID].continent, MapLib.blizzardConversion[MapLib.mapInfo[mapID].continentID].zone);
			else
				SetMapZoom(0);
			end;
		end;
	end;
end

MapLib.GetUnitMapPosition = function(unitID)
	if (MapLib.mapInfo[MapLib.mapShown].getPlayerMapPosition) then
		return MapLib.mapInfo[MapLib.mapShown].getPlayerMapPosition(unitID);
	else
		return 0, 0;
	end;
end

MapLib.GetCorpseMapPosition = function()
	if (MapLib.mapInfo[MapLib.mapShown].getCorpseMapPosition) then
		return MapLib.mapInfo[MapLib.mapShown].getCorpseMapPosition();
	else
		return 0, 0;
	end;
end;

MapLib.GetDeathReleasePosition = function()
	if (MapLib.mapInfo[MapLib.mapShown].getDeathReleasePosition) then
		return MapLib.mapInfo[MapLib.mapShown].getDeathReleasePosition();
	else
		return 0, 0;
	end;
end;

MapLib.GetPlayerContinentPosition = function()
	local x,y = GetPlayerMapPosition("player");
	return MapLib.ConvertToContinentCoordinates(MapLib.GetCurrentBlizzardMapMapID(), x, y);
end

-- Must be called after variables have been loaded!
MapLib.POI.RegisterForPOI = function(nameID, name, priority, submenu, getNumPOI, getPOI, getTooltip, isOnUpdate)
	if (not MapLib.poiDropDown) then MapLib.poiDropDown = {}; end;
	if (not MapLibSaved) then MapLibSaved = {}; end;
	if (not MapLibSaved.poiDropDown) then MapLibSaved.poiDropDown = {}; end;
	local menu = {
		nameID = nameID,
		name = name,
		priority = priority,
		getNumPOI = getNumPOI,
		getPOI = getPOI,
		getTooltip = getTooltip,
		isOnUpdate = isOnUpdate,
	};
	local isNewMenu, newMenuPosition = true, 1;
	for i, v in ipairs(MapLib.poiDropDown) do
		if (v.nameID == nameID) then
			v = menu;
			isNewMenu = false;
		end;
		if (v.priority < priority) then
			newMenuPosition = i+1;
		end;
	end;
	if (isNewMenu) then
		tinsert(MapLib.poiDropDown, newMenuPosition, menu)
	end;
	MapLib.POI.UpdateSubmenu(nameID, submenu);
end

MapLib.POI.UpdateSubmenu = function(nameID, submenu)
	for i, v in ipairs(MapLib.poiDropDown) do
		if (v.nameID == nameID) then
			v.submenu = submenu;
			if (not MapLibSaved.poiDropDown[nameID]) then MapLibSaved.poiDropDown[nameID] = {}; end;
			if (MapLibSaved.poiDropDown[nameID].isActivated == nil) then MapLibSaved.poiDropDown[nameID].isActivated = true; end;

			if (submenu) then
				for i=1, getn(submenu), 1 do
					if (MapLibSaved.poiDropDown[nameID][submenu[i].style] == nil) then 
						if (submenu[i].default ~= nil) then
							MapLibSaved.poiDropDown[nameID][submenu[i].style] = submenu[i].default;
						else
							MapLibSaved.poiDropDown[nameID][submenu[i].style] = true;
						end;
					end;
				end;
			end;
			-- since we may have changed hte look of default icons:
			MapLib.UpdatePOI("static");
			return;
		end;
	end;
end;

-- getPOI(zoneID, i) = return id, name, texture, x, y, style[, onLeftClick]
-- submenu if present table with submenu[i].texture, submenu[i].text, submenu[i].style, submenu[i].default info the same identifyer as in getPOI

MapLib.POI.RegisterMenuButton = function(name, callback, forModIDs, activeCheck)
	-- name can be a function or string!!
	-- for ModIDs can be nil for all or a table! of id's
	table.insert(MapLib.poiMenu, {
		name = name,
		callback = callback,
		forModIDs = forModIDs,
		activeCheck = activeCheck,
	} );
	-- callback arguments?? no clue lol
end

MapLib.poiMenu = MapLib.poiMenu or {
--	{ name = "Hallo",
--		callback = MapLib.CloseMenus,
--		forModIDs = nil,
--		canOutsideZoneMap = nil,
--	}, 
}
-- name as displayed
-- for mods = table of all mod names, nil for all, "static" only for those whose notes are not updated in "OnUpdate";
-- callback function to call function(modID, noteID, name, x, y, texture);

MapLib.Menu.RegisterButton = function(name, callback, activeCheck)
	tinsert(MapLib.menuButtons, getn(MapLib.menuButtons), {name, callback, activeCheck});
end

MapLib.menuButtons = MapLib.menuButtons or {
	{"Close", nil, function() return true; end},
};

--MapLib_RegisterMenuButton("Set Party/Raid Note", nil);
--MapLib_RegisterMenuButton("Set Guild Note", nil);
--MapLib_RegisterMenuButton("Create New Note", nil);

MapLib.ToggleMap = function()
	if (MapLibFrame:IsVisible()) then
		HideUIPanel(MapLibFrame);
	else
		ShowUIPanel(MapLibFrame);
	end;
end;

MapLib.Block.RedoGrayscale = function()
	if (MapLibBlockButton:IsShown()) then
		MapLib.Block.SetGrayscale();
	end;
end;

MapLib.Block.SetGrayscale = function()
	-- find out if shaders are suppored:
	local shaderSupported = MapLibDetailTile1:SetDesaturated(1);
	if (not shaderSupported) then
		MapLibDetailTile1:SetDesaturated(nil);
		MapLibBlockButtonTexture:Show();
	else
		MapLibBlockButtonTexture:Hide();
		for i=1, 12, 1 do
			getglobal("MapLibDetailTile"..i):SetDesaturated(1);
		end;
		for i=1, MapLib.NUM_OVERLAYS, 1 do
			getglobal("MapLibOverlay"..i):SetDesaturated(1);
		end;
		for i=1, MapLib.NUM_POIS, 1 do
			getglobal("MapLibPOI"..i.."Texture"):SetDesaturated(1);
		end;
	end;
	-- Disable the Options Button
	MapLibOptionsOpenCloseButton:Disable();
end;

MapLib.Block.ResetGrayscale = function()
	for i=1, 12, 1 do
		getglobal("MapLibDetailTile"..i):SetDesaturated(nil);
	end;
	for i=1, MapLib.NUM_OVERLAYS, 1 do
		getglobal("MapLibOverlay"..i):SetDesaturated(nil);
	end;
	for i=1, MapLib.NUM_POIS, 1 do
		getglobal("MapLibPOI"..i.."Texture"):SetDesaturated(nil);
	end;
	MapLibBlockButtonTexture:Hide();
	-- Disable the Options Button
	MapLibOptionsOpenCloseButton:Enable();
end;

MapLib.Block.OnClick = function()
	if (MapLibBlockButton.callback) then MapLibBlockButton.callback(); end;
end;

MapLib.Block.Request = function(ID, callback, frameLevel)
	--obviously ID and framelevel not supported yet.
	MapLibBlockButton:Show();
	MapLibBlockButton.callback = callback;
end;

MapLib.Block.Release = function(ID)
	MapLibBlockButton:Hide();
end;

-- /script ShowUIPanel(MapLib_WorldMapFrame);
-- /script SetupWorldMapScale(MapLib_WorldMapFrame); SetFullScreenFrame(MapLib_WorldMapFrame);


-- MapLib = { Localization = { Continents = { {id = "CO_KA", name = "Kalimdor"}, {id = "CO_EK", name = "Eastern Kingsoms"} } } };

MapLib.OnLoad();